package com.ayoka.base;

import android.app.Activity;
import android.databinding.DataBindingUtil;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.Snackbar;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.ayoka.R;
import com.jcp.baselibrary.networkstate.NetInfo;
import com.jcp.baselibrary.networkstate.NetWorkEvent;
import com.jcp.baselibrary.utils.MyLogger;
import com.jcp.baselibrary.utils.TDevice;
import com.jcp.baselibrary.utils.UIUtils;

import java.util.Observable;
import java.util.Observer;

/**
 * =========================================================
 * @ProjectName: 
 * @ClassName: BaseFragment
 * @Description: 作用描述
 * @Author: jincp
 * @CreateDate: 2019/3/14 13:51
 * =========================================================
 */
public abstract class BaseFragment<VDB extends ViewDataBinding, P extends BasePresenter> extends Fragment implements
        View.OnClickListener, IBaseView, IOnBackPressed, Observer {

    protected VDB mDataBinding;

    protected String TAG;

    // 参数在fragment可见时通过系统回调setUserVisibleHint方法设置为true,不可见时为false，这是fragment实现懒加载的关键。
    private boolean isVisible = true;
    // 参数在系统调用onActivityCreated时设置为true,这时onCreateView方法已调用完毕(一般我们在这方法里执行findViewById等方法),确保 initData()方法不会报空指针异常。
    private boolean isActivityCreated;
    // 确保ViewPager来回切换时BaseFragment的initData方法不会被重复调用，initData在该Fragment的整个生命周期只调用一次,第一次调用initData()方法后马上执行 isFirst = false。
    private boolean isFirst = true;

    protected P mPresenter;

    public void setFirst(boolean first) {
        isFirst = first;
    }

    public boolean isFirst() {
        return isFirst;
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        MyLogger.d(TAG, "setUserVisibleHint");
        isVisible = getUserVisibleHint();
        if (isVisible) {
            lazyLoad();
        } else {
            onInvisible();
        }
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        MyLogger.d(TAG, "onActivityCreated");
        isActivityCreated = true;
        lazyLoad();
    }


    @Override
    public void onCreate(Bundle savedInstanceState) {
        TAG = getClass().getSimpleName();
        NetWorkEvent.getInstance().addObserver(this);
        MyLogger.d(TAG, "onCreate");
        mPresenter = getPresenter();
        configBundleArguments();
        if (mPresenter != null) {
            mPresenter.attach(this);
        }
        super.onCreate(savedInstanceState);
    }

    @Override
    public void onResume() {
        super.onResume();
        MyLogger.d(TAG, "onResume");
    }

    @Override
    public void onPause() {
        super.onPause();
        MyLogger.d(TAG, "onResume");
    }

    protected void configBundleArguments() {
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        MyLogger.d(TAG, "onCreateView");
        View view = inflater.inflate(getContentLayout(), null);
        mDataBinding = DataBindingUtil.bind(view);
        //初始化事件和获取数据, 在此方法中获取数据不是懒加载模式
        initViews(view);
        return view;
    }

    protected abstract int getContentLayout();

    protected abstract void initViews(View view);

    protected abstract void initData();

    protected abstract P getPresenter();

    public void lazyLoad() {
        MyLogger.d(TAG, "lazyLoad" + isActivityCreated + isVisible + isFirst);
        if (!isActivityCreated || !isVisible || !isFirst) {
            return;
        }
        initData();
        isFirst = false;
    }

    //do something
    protected void onInvisible() {
        MyLogger.d(TAG, "onInvisible");
    }


    /**
     * 显示一个对话框 默认使用R.string.loading
     *
     * @return 返回一个加载的对话框控件
     */
    public void showWaitDialog() {
       showWaitDialog(UIUtils.getString(R.string.loading));
    }

    /**
     * 显示一个对话框
     *
     * @param message 使用系统中的自定义的文字显示
     * @return 返回一个加载的对话框控件
     */
    @Override
    public void showWaitDialog(String message) {
        Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && activity instanceof IBaseView) {
           ((IBaseView) activity).showWaitDialog(message);
        }
    }

    /**
     * 隐藏对话框
     */
    @Override
    public void hideWaitDialog() {
        Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && activity instanceof IBaseView) {
            ((IBaseView) activity).hideWaitDialog();
        }
    }

    @Override
    public void showToast(String message) {
        Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && activity instanceof IBaseView) {
           ((IBaseView) activity).showToast(message);
        }
    }

    @Override
    public Snackbar showSnackBar(View view, String content, int type) {
        Activity activity = getActivity();
        if (activity != null && !activity.isFinishing() && activity instanceof IBaseView) {
            return  ((IBaseView) activity).showSnackBar(view, content, type);
        }
        return null;
    }

    @Override
    public void onDestroy() {
        MyLogger.d(TAG, "onDestroy");
        hideWaitDialog();
        NetWorkEvent.getInstance().deleteObserver(this);
        if (mPresenter != null) {
            mPresenter.detachView();
            mPresenter = null;
        }
        super.onDestroy();
    }

    @Override
    public void onClick(View view) {
        TDevice.hideSoftKeyboard(view);
    }

    @Override
    public boolean onBackPressed() {
        return true;
    }

    @Override
    public void update(Observable observable, Object data) {
        if (observable instanceof NetWorkEvent) {
            NetInfo netInfo = (NetInfo) data;
            onNetworkState(netInfo.isNetworkAvailable, netInfo);
        }
    }

    /**
     * 网络状态
     *
     * @param isNetworkAvailable 网络是否可用
     * @param netInfo            网络信息
     */
    public void onNetworkState(boolean isNetworkAvailable, NetInfo netInfo) {
        MyLogger.d(TAG, "onNetworkState" + netInfo.networkType);
        if (isNetworkAvailable) {
//            showToast(R.string.network_is_available);
        } else {
            showToast(UIUtils.getString(R.string.network_is_not_available));
        }
    }
}
